package com.lhn.netty.netty_demo.codec;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;


/**
 * 处理任务的方法
 *
 * @author lhn
 * @date 2025/05/30 10:15
 * @since 1.0.0
 **/
/**
 说明:
 1. ChannelInboundHandlerAdapter: 是 Netty 提供的处理器抽象类
 2. 这是我们自定义的一个 handler , 才可以称为一个 handler
 * */
public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    // 读取数据实际方法
    /**
     ChannelHandlerContext ctx: 上下文对象, 含有管道 pipeline, 通道 channel, 地址
     Object msg: 服务器从客户端读取的数据, 默认是 object
     * */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 比如这里我们有一个非常耗时的操作, -> 异步执行 -> 提交给该channel 对应的 NIOEventLoop 的 taskQueue,
        // 解决方案1 用户程序自定义普通任务 taskQueue
        ctx.channel().eventLoop().execute(new Runnable() {

            @Override
            public void run() {
                try {
                    Thread.sleep(10000);
                    ctx.writeAndFlush(Unpooled.copiedBuffer("hello, client2", CharsetUtil.UTF_8));
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        ctx.channel().eventLoop().execute(new Runnable() {

            @Override
            public void run() {
                try {
                    Thread.sleep(20000);
                    ctx.writeAndFlush(Unpooled.copiedBuffer("hello, client3", CharsetUtil.UTF_8));
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        // 用户自定义的定时任务 -> 该任务提交到 scheduleTaskQueue
        ctx.channel().eventLoop().schedule(new Runnable() {

            @Override
            public void run() {
                try {
                    Thread.sleep(10000);
                    ctx.writeAndFlush(Unpooled.copiedBuffer("hello, client4", CharsetUtil.UTF_8));
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }, 5, java.util.concurrent.TimeUnit.SECONDS);


        System.out.println("go on");

        //System.out.println("服务器读取线程 " + Thread.currentThread().getName());
        //System.out.println("server ctx = " + ctx);
        //Channel channel = ctx.channel();
        //ChannelPipeline pipeline = ctx.pipeline(); //本质是一个双向链接, 出站入站
        //// // 将msg 转成一个 ByteBuf
        //// ByteBuffer 是 netty 提供的, 是 Netty 的字节缓冲区, 是 Netty 的优化内存模型
        //ByteBuf buffer = (ByteBuf) msg;
        //System.out.println("客户端发送消息是: " + buffer.toString(CharsetUtil.UTF_8));
        //System.out.println("客户端地址: " + ctx.channel().remoteAddress());
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.out.println("服务器读取数据完毕");
        // 将数据写入到缓存, 并刷新
        // 将数据写入到缓存并刷新
        // 一般讲, 我们对  发送的数据进行编码
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello, client1", CharsetUtil.UTF_8));
    }

    // 处理异常 , 一般需要关闭通道
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }

}